package com.zlf.sb.demo.juc;

/***
 *@title ParallelPaginationQuery
 *@description <TODO description class purpose>
 *@author wgc_j
 *@version 1.0.0
 *@create 2025-03-06 13:27
 **/
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Collectors;

// 公共分页查询类
public class ParallelPaginationQuery<T> {

    // 线程池
    private final ExecutorService executorService;

    public ParallelPaginationQuery(int threadPoolSize) {
        this.executorService = Executors.newFixedThreadPool(threadPoolSize);
    }

    /**
     * 并行分页查询方法
     * @param pageSize 每页大小
     * @param totalPages 总页数
     * @param queryFunction 查询函数，输入页码，返回该页数据列表
     * @return 合并后的所有页数据列表
     */
    public List<T> queryParallel(int pageSize, int totalPages, Function<Integer, List<T>> queryFunction) {
        List<CompletableFuture<List<T>>> futures = new ArrayList<>();

        // 为每一页创建一个 CompletableFuture 任务
        for (int page = 1; page <= totalPages; page++) {
            int finalPage = page;
            CompletableFuture<List<T>> future = CompletableFuture.supplyAsync(() -> queryFunction.apply(finalPage), executorService);
            futures.add(future);
        }

        // 等待所有任务完成并合并结果
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        CompletableFuture<List<List<T>>> allPageResults = allFutures.thenApply(v -> {
            return futures.stream()
                    .map(CompletableFuture::join)
                    .collect(Collectors.toList());
        });

        try {
            // 合并所有页的数据
            return allPageResults.get().stream()
                    .flatMap(List::stream).collect(Collectors.toList());

        } catch (InterruptedException | ExecutionException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("并行查询出错", e);
        }
    }

    // 关闭线程池
    public void shutdown() {
        executorService.shutdown();
    }

    public static void main(String[] args) {

            // 创建并行分页查询实例，指定线程池大小
            ParallelPaginationQuery<String> query = new ParallelPaginationQuery<>(4);

            // 模拟分页查询函数
            Function<Integer, List<String>> queryFunction = page -> {
                List<String> pageData = new ArrayList<>();
                for (int i = 0; i < 10; i++) {
                    pageData.add("Page " + page + " - Item " + i);
                }
                return pageData;
            };

            // 执行并行分页查询
            List<String> result = query.queryParallel(10, 5, queryFunction);

            // 输出结果
            result.forEach(System.out::println);

            // 关闭线程池
            query.shutdown();
        }

}